import 'dart:io';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:test1/View/TextWdigetPage.dart';

void main() {
  foo1();
  foo2();

  runApp(new MyApp());
  runApp(new _MyDemoApp());
  runApp(new TestApp());
}

class TestApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return TestAppState();
  }
}

class TestAppState extends State<TestApp> {
  final list = [
    ItemInfo("页面间跳转"), ItemInfo("页面间跳转"), ItemInfo("页面间跳转"), ItemInfo("页面间跳转")];


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "flutter学习",
      home: Scaffold(
        appBar: AppBar(
          title: Text("flutter学习"),
        ),
        body: ListView.builder(
            itemCount: list.length,
            itemBuilder: (context, position) {
              return ItemView(position, list[position], context, (index) =>
                  Navigator.push(
                      context, new MaterialPageRoute(builder: (BuildContext context) {
                    return new TextWdigetPage();
                  }))
              );
            }),
      ),
    );
  }

}

class ItemInfo {
  String title;

  ItemInfo(this.title);
}

// 定义一个回调接口
typedef OnItemClickListener = void Function(int position);

class ItemView extends StatelessWidget {


  int position;
  ItemInfo iteminfo;
  BuildContext context;
  OnItemClickListener listener;

  ItemView(this.position, this.iteminfo, this.context, this.listener);

  _onItemClick() {
    Navigator.push(
        context, new MaterialPageRoute(builder: (BuildContext context) {
      return new TextWdigetPage();
    }));
    debugPrint("111");
  }

  @override
  Widget build(BuildContext context) {
    var widget = Column(
      children: <Widget>[
        Row(
          children: <Widget>[
            Text(
              iteminfo.title,
              style: TextStyle(
                fontSize: 15.0,
                color: Color.fromARGB(255, 51, 51, 51),
              ),
            )
          ],
        ),
        Divider()
      ],
    );
    return InkWell(
        onTap: () => listener(position),
        child: widget
    );
  }
}


class _MyDemoApp extends StatelessWidget {

  var titleSection = _TitleSection("这是一个标题", "这是副标题", 20);
  var buttonSection = _ButtonSection();
  var textSection = Container(
    padding: EdgeInsets.all(30.0),
    child: Text(
      "噢噢噢噢哦哦哦哦哦哦哦哦哦哦哦噢噢噢噢哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦哦",
      softWrap: true,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "最近打开的标题",
      home: Scaffold(
          appBar: AppBar(
            title: Text("标题"),
          ),
          body: ListView(
            children: <Widget>[
              Image.network(
                "http://pic1a.nipic.com/2009-01-07/20091713417344_2.jpg",
                width: 100.0,
                height: 300.0,
                fit: BoxFit.cover,
              ),
              titleSection,
              buttonSection,
              textSection
            ],
          )
      ),
    );
  }
}

class _TitleSection extends StatelessWidget {
  final String title;
  final String subTitle;
  final int startCount;

  _TitleSection(this.title, this.subTitle, this.startCount);

  @override
  Widget build(BuildContext context) {
    return Container(
      // 为了给 title 加上 padding，这里我们给内容套一个 Container
      padding: EdgeInsets.all(32.0),
      child: Row(
        children: <Widget>[
          // 这里为了让标题占满屏幕宽度的剩余空间，用 Expanded 把标题包了起来
          Expanded(
            child: Column(
              // Column 是竖直方向的，cross 为交叉的意思，也就是说，这里设置的是水平方向
              // 的对齐。在水平方向，我们让文本对齐到 start（读者可以修改为 end 看看效果）
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[

                Container(
                  padding: EdgeInsets.only(bottom: 10.0),
                  child: Text(
                    title,
                    style: TextStyle(
                        fontSize: 15.0
                    ),
                  ),
                ),
                Text(subTitle, style: TextStyle(
                    fontSize: 13.0,
                    color: Color.fromARGB(255, 99, 99, 99)
                ),)
              ],
            ),
          ),
          Icon(
            Icons.star,
            color: Colors.red[500],
          ),
          Text(startCount.toString()),
        ],
      ),
    );
  }

}

Widget _button(BuildContext context, IconData icon, String label) {
  final color = Theme
      .of(context)
      .primaryColor;

  return Column(
    // main axis 跟我们前面提到的 cross axis 相对应，对 Column 来说，指的就是竖直方向。
    // 在放置完子控件后，屏幕上可能还会有一些剩余的空间（free space），min 表示尽量少占用
    // free space；类似于 Android 的 wrap_content。
    // 对应的，还有 MainAxisSize.max
    mainAxisSize: MainAxisSize.min,
    // 沿着 main axis 居中放置
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      Icon(icon, color: color,),
      Container(
        margin: EdgeInsets.only(top: 10.0),
        child: Text(
          label,
          style: TextStyle(
              fontSize: 12.0,
              color: color,
              fontWeight: FontWeight.w400
          ),
        ),
      )
    ],
  );
}

class _ButtonSection extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <Widget>[
        _button(context, Icons.call, 'CALL'),
        _button(context, Icons.near_me, 'ROUTE'),
        _button(context, Icons.share, 'SHARE')
      ],
    );
  }

}


/**
 * 顶层的widget，
 * 无状态的继承StatelessWidget，
 * 有状态的继承StatefulWidget
 * StatelessWidget和StatefulWidget的区别：https://blog.csdn.net/qq_30295213/article/details/80663394
 * stateless widget 整个生命周期里都不会改变，所以 build 方法只会执行一次。而 stateful widget 只要状态改变，就会调用 build 方法重新创建 UI。
 */
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
//    使用MeterialDesign风格，这里new一个MaterialApp
    return new MaterialApp(
      // 移动设备使用这个 title 来表示我们的应用。具体一点说，在 Android 设备里， 打开最近应用列表的时候，显示的就是这个 title。
      title: 'Flutter Demo',
      //应用的主题
      theme: new ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or press Run > Flutter Hot Reload in IntelliJ). Notice that the
        // counter didn't reset back to zero; the application is not restarted.
        primarySwatch: Colors.blue,
      ),
      //应用主页面
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  MyWidget createState() => new MyWidget();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  final _random = Random();

  List<int> _roll() {
    final rool1 = _random.nextInt(6) + 1;
    final rool2 = _random.nextInt(6) + 1;
    return [rool1, rool2];
  }

  void _onPressed() {
    debugPrint("_onPressed!!!!!!!!!!!!");
    final rollResult = _roll();
    showDialog(
      // 第一个 context 是参数名，第二个 context 是 State 的成员变量
        context: context,
        builder: (_) {
          return AlertDialog(
            content: Text("RollResults:(${rollResult[0]},${rollResult[1]})"),
          );
        }
    );
  }

  void _add(int x, [int y = 3]) {
    if (y == null) {
      print(x);
    }
    print(x + y);
  }

  /**
   * 用具名参数，参数需要用大括号括起来
   * 可以用默认值
   * @required 该参数是必须的
   */
  void _sum({@required int x, int y = 0}) {
    print(x + y);
  }

  void _onCompute() {
    int age = 12;
    bool man = true;
    double height = 1.75;

    //final运行时常量,在程序运行的时候赋值，赋值后值不再改变
    final int num = 123;
    final bool woman = false;
    final double weight = 1.1;

//const 表示一个编译时常量，在程序编译的时候它的值就确定了。
    const int id = 12;
    const bool isfirst = true;

    var idCard = 321;
    var isFirst = true;

    final a = 111;
    const b = true;

    String name = "张三";
    var newName = "张三";

    if (identical(name, newName)) {
      debugPrint("111");
    } else {
      debugPrint("222");
    }

    if (age == 13) {
      debugPrint("相等");
    } else {
      debugPrint("不相等");
    }

    var list = List<int>();
    list.add(1);
    list.add(2);
//    debugPrint("list的长度：");

    var list1 = new List<int>();

    var list2 = [1, 2];

    var list3 = <int>[];

    var list4 = const[1, 2]; // list4 指向的是一个常量，我们不能给它添加元素（不能修改它）
    // list4 本身不是一个常量，所以它可以指向另一个对象
    list4 = [4, 5, 6];

    const list5 = [1, 2]; //等价于 var list4 = const[1, 2];


    var list6 = [1, 2, 3, 4, 5, 6];
    for (var i in list6) {
      print(i);
    }

    var set = Set<String>();
    set.add("AAA");
    set.add("BBB");
    assert(set.contains("AAA"));

    var map = Map<String, int>();
    map["abc"] = 1;
    map["cde"] = 2;
    map["fgh"] = 3;
    print("cde对应的值：${map["cde"]}");
    map["cde"] = 4;
    print("修改后cde对应的值：${map["cde"]}");

    if (map["mn"] == null) {
      print("key不存在");
    }

    var map2 = const{
      "num": 123,
      "name": "xiaoming"
    };

    var map3 = <String, String>{};
    map3["aaa"] = "lisi";
    map3["abc"] = "zhangsan";

    if (map3 is Map<String, String>) {
      map3["bbb"] = "wangwu";
    }
    for (var key in map3.keys) {
      print("$key--${map3[key]}");
    }

    _add(1);

    _sum(x: 1, y: 2);
    _sum(x: 1);
    _sum(x: 0, y: 2);
  }

  /**
   * 类
   */
  void _setPoint() {
    var point = OffsetPoint(1, 2, 5);

    // 使用 getter/setter 时，就像它是一个普通的成员变量
    print("x值为：${point.x}");
    print("y值为：${point.y}");

    point.x = 11;
    print(point.toString());
  }

  /**
   * 泛型类
   */
  void _jenericity() {
    var pair = Pair(123, "abc");

    if (pair is Pair<int, String>) {
      print(pair.first);
    } else {
      print(pair.second);
    }

    print(pair.toString());
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return new Scaffold(
      appBar: new AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: new Text(widget.title),
      ),
      body: new Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: new Column(
          // Column is also layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Invoke "debug paint" (press "p" in the console where you ran
          // "flutter run", or select "Toggle Debug Paint" from the Flutter tool
          // window in IntelliJ) to see the wireframe for each widget.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme
                  .of(context)
                  .textTheme
                  .display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _jenericity,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

}

/**
 * 普通类
 */
class OffsetPoint {
//  不想某个变量对包的外部可见，可以使用下划线开头来给变量命名
  int _x;
  int _y;
  int offset;

//  初始化
//  OffsetPoint(int _x, int _y, int offset) {
//    this._x = _x;
//    this._y = _y;
//    this.offset = offset;
//  }

//  简化的初始化
//  OffsetPoint(this._x, this._y, this.offset) {}

//  使用初始化列表（initializer list）对对象进行初始化
  OffsetPoint(int _x, int _y, int offset)
      :
        _x = _x,
        _y=_y,
        offset=offset {}

  // 定义一个 getter,// getter 不能有参数，连括号都省掉了
  int get x => _x + offset;

  int get y {
    return _y + offset;
  }

// 定义 setter
  void set x(int x) {
    _x = x;
  }

  void set y(int y) {
    _y = y;
  }

  @override
  String toString() {
    return "point($x,$y)，offset is $offset";
  }
}

/**
    类的继承
    1.先执行子类 initializer list，但只初始化自己的成员变量
    2.初始化父类的成员变量
    3.执行父类构造函数的函数体
    4.执行之类构造函数的函数体
 */
class Point3D extends OffsetPoint {
  int _z;

  // 父类的构造函数只能在 initializer list 里调用
  Point3D(int x, int y, int z, int offset)
      :_z=z,
        super(x, y, offset);

}

/**
 * 泛型类
 */
class Pair<S, T> {
  S _first;
  T _second;

  Pair(this._first, this._second);

  S get first {
    return _first;
  }

  T get second => _second;

  void set first(S first) {
    _first = first;
  }

  void set second(T _second) {
    this._second = _second;
  }
}

/**
 * 线程
 * Dart 是单线程的，主线程由一个事件循环来执行（类似 Android 的主线程）
 */
void foo1() {
  var file = File("new_file");
  file.exists()
      .then((exists) =>
      print('!!!!!!!!!!!!!!!!!foo1:new_file${exists
          ? ' is exists'
          : 'not is exists'}'))
      .catchError((e) => print(e));
  print("!!!!!!!!!!!!!!!!!foo1 is end");
}

void foo2() async {
  var file = File("new_file");
  var exists = await file.exists();
  if (exists) {
    print("!!!!!!!!!!!!!!!!!new_file is exists");
  } else {
    print("!!!!!!!!!!!!!!!!!new_file not is exists");
  }
  print("!!!!!!!!!!!!!!!!!foo2 is end");
}


class MyWidget extends State<MyHomePage> {

  var editController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    var text = Text(
      "文本组件",
      style: TextStyle(
          color: Colors.red,
          fontSize: 25.0
      ),
    );

    var image = Image.network(
      "http://pic1a.nipic.com/2009-01-07/20091713417344_2.jpg",
      width: 100.0,
      height: 100.0,
    );

    var flatButton = FlatButton(
//        onPressed 可以在按钮被点击的时候得到回调
        onPressed: () => print("flatbutton"),
//        child 参数用于设置按钮的内容
//        child 可以接受任意的 Widget，比方说，Image
        child: Text("FlatButton"
            , style: TextStyle(
              fontSize: 14.0,
            ))

    );

    var raisedButton = RaisedButton(
      onPressed: () =>
          showDialog(
              context: context, // 第一个 context 是参数名，第二个 context 是 State 的成员变量
              builder: (_) {
                return AlertDialog(
                  // dialog 的内容
                  content: Text("点我干嘛"),
                  // actions 设置 dialog 的按钮
                  actions: <Widget>[
                    FlatButton(
                        child: Text("OK"),
                        // 用户点击按钮后，关闭弹框
                        onPressed: () => Navigator.pop(context)
                    ),
                    FlatButton(
                        child: Text("cancle"),
                        // 用户点击按钮后，关闭弹框
                        onPressed: () => Navigator.pop(context)
                    )
                  ],
                );
              }),
      child: Text("RaisedButton"),
    );

    var row1 = Row(
      children: <Widget>[
        Expanded(
          child: TextField(
            controller: editController,
          ),
        ),
        RaisedButton(
          child: Text("click"),
          onPressed: () => print('text inputted: ${editController.text}'),
        )
      ],
    );

    var container = Container(
      child: Center(
        child: Text("Container容器"),
      ),
      padding: EdgeInsets.all(50.0),
      margin: EdgeInsets.all(10.0),
      width: 200.0,
      height: 200.0,
      decoration: BoxDecoration(
          color: Colors.grey,
          borderRadius: BorderRadius.circular(10.0)
      ),
    );

    var padding = Padding(
      padding: EdgeInsets.all(40.0),
      child: Text("Padding控件"),
    );

    var row = Row(
      children: <Widget>[
        Text("文本1",
          style: TextStyle(
              fontSize: 12.0
          ),
        ),
        Text("文本2"),
        Text("文本3"),
        Text("文本4"),
      ],
    );

    var colomn = Column(
      children: <Widget>[
        Text("文本1"),
        Text("文本2"),
        Text("文本3"),
        Text("文本4"),
      ],
    );

    /**
     * expanded填充剩下的空间，flex可以设置占比
     */
    var expanded = Row(
      children: <Widget>[
        Expanded(
            flex: 2,
            child: RaisedButton(onPressed: () => {},
                child: Text("文本", style: TextStyle(color: Colors.red)))
        ),
        Expanded(
            flex: 1,
            child: RaisedButton(onPressed: () => {},
              child: Text("文本2", style: TextStyle(color: Colors.red)),)
        ),
        RaisedButton(onPressed: () => {},
            child: Text("文本3", style: TextStyle(color: Colors.red)))
      ],
    );


    var stack = Stack(
      alignment: Alignment(-0.5, -0.5),
      children: <Widget>[
        Text("abcdefg"),
        Text("1234567")
      ],
    );
    return stack;
  }

  @override
  void dispose() {
    super.dispose();
    // 手动调用 controller 的 dispose 方法以释放资源
    editController.dispose();
  }

}